#include "stdafx.h"
#include "CommandFunctionDefine.h"
#include "ParamBase.h"
#include "UIClass.h"
#include "RoadGroup.h"
#include "ogrewidget.h"
#include "LoadUICfg.h"
#include<QtGui\\QMatrix4x4>
#pragma region COMMAND_READ
int SelectObjectChange(const ZMVector<SharedPointer<CNameCreateBase>>& vData)
{
#ifdef USE_UNITY3D
	string strName = ((CTemplateParam<string>*)vData[0].get())->GetData();
	GetMainWnd()->SelChange(ToQString(strName));
#endif
	return 0;
}

 
static SharedPointer<UIDataBase> FindObjParam(const QString& objName, const QString& idRelation, const QString& templateID, const QString& strParamName)
{
	SharedPointer<UIDataBase> ret;
	UITemplate uiTemp;
	if (CLoadUICfg::GetInstance()->FindTemplateUIFromObj(objName, idRelation, templateID, uiTemp) == 0)
	{
		ZMVector<SharedPointer<UIDataBase>> vParam = uiTemp.GetParam();
		for (SharedPointer<UIDataBase> pParam : vParam)
		{
			if (pParam->GetID() == strParamName)
			{
				ret = pParam;
			}
		}
	}
	return ret;
}

static ZMReal GetVarRealValue(SharedPointer<UIDataBase> pParam)
{
	ZMReal fValue;
	pParam->GetValueAsReal(fValue);
	return fValue;
}


static int GetVarIntValue(SharedPointer<UIDataBase> pParam)
{
	int fValue;
	pParam->GetValueAsInt(fValue);
	return fValue;
}


static ZMString GetVarStringValue(SharedPointer<UIDataBase> pParam)
{
	QString fValue;
	pParam->GetValueAsString(fValue);
	return ToString(fValue);
}



static QString m_sParentName, m_sObjName;
void UpdateName(QString sParentName, QString sObjName)
{
	m_sParentName = sParentName;
	m_sObjName = sObjName;
}

static ZMReal GetParentVarReal(QString strParamName, const QString& idRelation="", const QString& templateID = "")
{
	SharedPointer<UIDataBase> pParam = FindObjParam(m_sParentName, idRelation, templateID, strParamName);
	return GetVarRealValue(pParam);
}

static int GetParentVarInt(QString strParamName, const QString& idRelation = "", const QString& templateID = "")
{
	SharedPointer<UIDataBase> pParam = FindObjParam(m_sParentName, idRelation, templateID, strParamName);
	return GetVarIntValue(pParam);
}

static ZMString GetParentVarString(QString strParamName, const QString& idRelation = "", const QString& templateID = "")
{
	SharedPointer<UIDataBase> pParam = FindObjParam(m_sParentName, idRelation, templateID, strParamName);
	return GetVarStringValue(pParam);
}

static ZMReal GetVarReal(QString strParamName, const QString& idRelation = "", const QString& templateID = "")
{
	SharedPointer<UIDataBase> pParam = FindObjParam(m_sObjName, idRelation, templateID, strParamName);
	return GetVarRealValue(pParam);
}

static int GetVarInt(QString strParamName, const QString& idRelation = "", const QString& templateID = "")
{
	SharedPointer<UIDataBase> pParam = FindObjParam(m_sObjName, idRelation, templateID, strParamName);
	return GetVarIntValue(pParam);
}

static ZMString GetVarString(QString strParamName, const QString& idRelation = "", const QString& templateID = "")
{
	SharedPointer<UIDataBase> pParam = FindObjParam(m_sObjName, idRelation, templateID, strParamName);
	return GetVarStringValue(pParam);
}

int RotateChange(const ZMVector<SharedPointer<CNameCreateBase>>& vData)
{
	ZMString strObjName = ((CTemplateParam<ZMString>*)(vData[0]).get())->GetData();
	RotateData dataRotate = ((CTemplateParam<RotateData>*)(vData[1]).get())->GetData();
	OgreWidget* pWidget = GetMainWnd()->GetMain3dWindow();
	bool isAbs = true;
	ZMPoint3D pntAxis = dataRotate.GetAxis();
	ZMPoint3D pntOrign = dataRotate.GetPntAxisOrign();
	ZMReal fAngle = dataRotate.GetAngle();
	RotateData::ROTATE_TYPE oType = dataRotate.GetRotateType();

	if (oType == RotateData::TYPE_REL)
	{
		isAbs = false;
	}
	if (fabs(fAngle) > 0.0001)
	{
		pWidget->RotateObj(strObjName , pntOrign, pntAxis, fAngle*3.1415 / 180.0, isAbs);
	}

	return 0;
}

int OffsetChange(const ZMVector<SharedPointer<CNameCreateBase>>& vData)
{
	ZMString strObjName = ((CTemplateParam<ZMString>*)(vData[0]).get())->GetData();
	OffsetData dataOffset = ((CTemplateParam<OffsetData>*)(vData[1]).get())->GetData();
	OgreWidget* pWidget = GetMainWnd()->GetMain3dWindow();
	OffsetData::OFFSET_TYPE oType = dataOffset.GetMoveType();
	bool isAbs = true;
	ZMPoint3D pntAxis = dataOffset.GetAxis();
	ZMReal fOffset = dataOffset.GetDis();

	if (fabs(fOffset) < 0.0001) return 0;

	if (oType == OffsetData::TYPE_WITH_ROAD)
	{
		PRoadGroup pRoadGroup = GetMainWnd()->GetRoadGroup();
		PRoadDesign pRoad = pRoadGroup->FindRoad(dataOffset.GetRoadName());
		SharedPointer<RoadMileLine> pMileLine = pRoad->GetCrossData()->GetMileData();
		ZMPoint3D pnt = dataOffset.GetAxis() * dataOffset.GetDis();

		ZMPoint3D pntOnMile;
		ZMReal fAngle;
		if (!pMileLine->GetMileData(pnt[0], pntOnMile, fAngle))
		{
			ZMPoint3D xAxis = pMileLine->GetMileDir(pntOnMile); xAxis.Normalize();
			ZMPoint3D yAxis = pMileLine->GetVerticalDir(pnt[0]); yAxis.Normalize();
			ZMPoint3D zAxis = xAxis.Crossed(yAxis); zAxis.Normalize();
			if (zAxis[2] < 0) zAxis *= -1;
			ZMPoint3D pntTemp ;
			pntTemp = pntOnMile + yAxis*pnt[1] + zAxis*pnt[2];
			pntAxis = pntTemp;
			fOffset = 1;
		}

	}
	else if (oType == OffsetData::TYPE_REL)
	{
		isAbs = false;
	}

	if (fabs(fOffset) > 0.0001)
	{
		pWidget->OffsetObj(strObjName, pntAxis, fOffset * 0.01, isAbs);
	}
	return 0;
}


void GetRegFuncInfo(ZMVector<QString>& vFuncName, ZMVector<RunFunction>& vRunFuncName)
{
	vFuncName = { "SelectObjectChange", "OffsetChange", "RotateChange" };
	vRunFuncName = { 
		boost::bind(&SelectObjectChange, _1),
		boost::bind(&OffsetChange, _1),
		boost::bind(&RotateChange, _1)
	};
}
 ZMVector<RunFunction>  m_vFunc = { boost::bind(&SelectObjectChange, _1), boost::bind(&OffsetChange, _1) };

void InitFunction()
{
	ZMVector<QString> vFuncName;
	ZMVector<RunFunction> vRunFuncName;
	GetRegFuncInfo(vFuncName, vRunFuncName);
	for (int i = 0;i < vFuncName.size(); ++i)
	{
		CObjectCreateFromName::GetInstance()->AddFunction(vFuncName[i], vRunFuncName[i]);
	}
}
#pragma endregion COMMAND_READ
